package com.zhiwang.planet.ui.my

import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.text.TextUtils
import android.view.*
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import com.cmcm.cmgame.CmGameSdk
import com.cmcm.cmgame.IGameAccountCallback
import com.cmcm.cmgame.IGamePlayTimeCallback
import com.zhiwang.planet.R
import com.zhiwang.planet.databinding.FragmentMinigameBinding
import com.zhiwang.planet.di.component.DaggerUserComponent
import com.zhiwang.planet.di.module.AccountModule
import com.zhiwang.planet.di.module.AutoDisposeModule
import com.zhiwang.planet.mvp.p.UserPresenter
import com.zhiwang.planet.mvvm.model.RestApi
import com.zhiwang.planet.mvvm.model.entity.main.TinyGameAccountInfo
import com.zhiwang.planet.mvvm.model.request.GamePlayTimeReport
import com.zhiwang.planet.mvvm.viewmodel.ItemDecorationViewModel
import com.zhiwang.planet.mvvm.viewmodel.entertain.MyPlayedGameViewModel
import com.zhiwang.planet.mvvm.viewmodel.entertain.PlayGameConnection
import com.zhiwang.planet.mvvm.viewmodel.entertain.mapMyPlayedGme
import com.zhiwang.planet.ui.BaseFragment
import com.zhiwang.planet.util.*
import kotlinx.android.synthetic.main.play_time_dialog.view.*
import kotlinx.coroutines.*
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext

class MiniGameFragment : BaseFragment(),IGameAccountCallback, IGamePlayTimeCallback ,CoroutineScope{


    fun initInjection() {

        DaggerUserComponent.builder()
                .accountModule(AccountModule(requireActivity() as AppCompatActivity))
                .appComponent(getAppComponent())
                .autoDisposeModule(AutoDisposeModule(this))
                .build()
                .inject(this)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initInjection()
    }

    @Inject
    lateinit var myGameViewModel: MyPlayedGameViewModel


    @Inject
    lateinit var decorationViewModel: ItemDecorationViewModel

    @Inject
    lateinit var userPresenter: UserPresenter

    private var gameStartTime = System.currentTimeMillis()

    private var playing = false

    @Inject
    lateinit var restApi: RestApi

    var gameId: String = ""

    private var currToken: String = ""

    private val removeIds = arrayListOf<String>()

    private var active = false

    private lateinit var mJob: Job

    override val coroutineContext: CoroutineContext
        get() = mJob + Dispatchers.Main

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val root = inflater.inflate(R.layout.fragment_minigame, container, false)

        val binding = DataBindingUtil.bind<FragmentMinigameBinding>(root)
        binding?.lifecycleOwner = viewLifecycleOwner
        myGameViewModel.errHandler = this::onError
        binding?.vm = myGameViewModel
        binding?.playVm = PlayGameConnection
        binding?.decorVm = decorationViewModel

        myGameViewModel.start()

        PlayGameConnection.playGame.observe(viewLifecycleOwner, Observer {
            playMiniGame(it)
        })

        PlayGameConnection.checkedGame.observe(viewLifecycleOwner, Observer {
            addRemoveGame(it)
        })

        PlayGameConnection.uncheckedGame.observe(viewLifecycleOwner, Observer {
            subRemoveGame(it)
        })

//        PlayGameConnection.selectActive.observe(viewLifecycleOwner, Observer { invalidateOptionsMenu() })

        CmGameSdk.setGameAccountCallback(this)

        CmGameSdk.setGamePlayTimeCallback(this)

        active = true
        return root
    }

    private fun subRemoveGame(id: String) = removeIds.remove(id)


    private fun addRemoveGame(id: String) = removeIds.add(id)


    fun removeGame(view: View) {

        launch {
            val restGames = withContext(Dispatchers.IO) { restApi.deleteMyPlayedGame(removeIds).data }

            myGameViewModel.gameData.value = mapMyPlayedGme(restGames)

        }
    }


//    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
//        if (PlayGameConnection.selectActive.value == false)
//            menuInflater.inflate(R.menu.menu_delete, menu)
//        else menuInflater.inflate(R.menu.menu_complete, menu)
//        return super.onCreateOptionsMenu(menu)
//    }





    fun playMiniGame(gameId: String) {

        if (!isTokenValid()) {
            launchDelayError(errHandler = ::onError) {

                val token2 = restApi.getMiniGameTempToken2().data
                currToken = token2
                CmGameSdk.startH5Game(gameId)
            }
            return
        }

        if (CmGameSdk.hasGame(gameId).not())
            return Toaster.message("该游戏暂时无法运行，请试玩其他游戏($gameId)")

        this.gameId = gameId
        val tinyGameAccount = TokenManager.miniGameAccount()
        if (TokenManager.hasMiniGameAccount().not()) //还没有提交过后台服务器游戏账户信息，请求后台服务器游戏账户信息
            launch {
                try {
                    val res = retryIO { restApi.getMiniGameAccount() }
                    val playToken = res.data.miniGameToken ?: ""
                    currToken = playToken
                    if (playToken.isEmpty())
                        createAccountAndPlayGame()
                    else
                        restoreAccountAndPlayGame(currToken)
                } catch (e: Exception) {
                    onError(e)
                }

            }
        else {
            //直接使用本地缓存的游戏账户
            restoreAccountAndPlayGame(tinyGameAccount)
            userPresenter.postTinyGameLoggedAccountInfo(tinyGameAccount, ::onError)
        }


    }


    fun isTokenValid(): Boolean {
        return TextUtils.isEmpty(currToken).not()
    }

    /**
     * 使用之前缓存的游戏账号继续 玩游戏
     */
    fun restoreAccountAndPlayGame(accountToken: String) {
        if (playing) return
        CmGameSdk.restoreCmGameAccount(accountToken)
        playing = true
        gameStartTime = System.currentTimeMillis()
        CmGameSdk.startH5Game(gameId)


    }

    /**
     * 创建游戏账户后 玩游戏
     */
    private fun createAccountAndPlayGame() {
        if (playing) return
        CmGameSdk.restoreCmGameAccount(null)
        CmGameSdk.clearCmGameAccount()
        playing = true
        gameStartTime = System.currentTimeMillis()
        CmGameSdk.startH5Game(gameId)
    }


    override fun onGameAccount(accountToken: String) {

        TokenManager.saveMiniGameAccount(accountToken)

        launch {
            try {
                restApi.postTinyGameAccountInfo(TinyGameAccountInfo(accountToken))
            } catch (e: Exception) {
                onError(e)
            }
        }

    }

    override fun gamePlayTimeCallback(gameId: String, gamePlayedTimeSeconds: Int) {
        if (active.not())
            return
        playing = false


        val req = GamePlayTimeReport(gameId, gamePlayedTimeSeconds, MD5.getMD5(gameId + gamePlayedTimeSeconds + currToken).toLowerCase())

        launch {
            val gamePlayTime = restApi.postGamePlayTime2(req)
            if (gamePlayTime.isOk()){
                onPlayTimeHandleIn(gamePlayTime.data.diamondRewardNum, gamePlayTime.data.beanRewardNum)
                val res = restApi.getMiniGameTempToken2()
                currToken = res.data
            }else{
                onError(gamePlayTime.error())
            }

        }
    }


    fun onPlayTimeHandleIn(msg: String?, beanReward: String?) {
        currToken = ""
        val view = layoutInflater.inflate(R.layout.play_time_dialog, null)


        val create = AlertDialog.Builder(requireActivity())
                .setView(view)
                .create()

        view.tv_reward_diamond.visibility = if (TextUtils.isEmpty(msg)) View.GONE else View.VISIBLE
        view.tv_reward_diamond.text = "+$msg"

        view.tv_reward_bean.visibility = if (TextUtils.isEmpty(beanReward)) View.GONE else View.VISIBLE
        view.tv_reward_bean.text = "+$beanReward"

        view.dialog_button.setOnClickListener {
            apply {
                create.dismiss()
            }
        }
        create.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        create.show()
    }


//    override fun onSupportNavigateUp(): Boolean {
//        if (PlayGameConnection.selectActive.value == true) {
//
//            PlayGameConnection.selectActive.value = false
//            return false
//        }
//        onBackPressed()
//        return super.onSupportNavigateUp()
//    }


//    override fun onBackPressed() {
//        if (PlayGameConnection.selectActive.value == true) {
//
//            PlayGameConnection.selectActive.value = false
//            PlayGameConnection.cancelGame.value = removeIds
//            removeIds.clear()
//            return
//        }
//        super.onBackPressed()
//    }

    override fun onDestroy() {
        super.onDestroy()
        active = false
        PlayGameConnection.reset()
    }


}